﻿Imports Microsoft.Office.Interop
Imports System.IO

''' <summary>
''' Wrapper for svn
''' </summary>
''' <remarks></remarks>
Public Class SVNClient

    Public ReadOnly Property svnExecutablePath As String
        Get
            Return GetSetting("AccessSvn", "settings", "svnExecutablePath")
        End Get
    End Property

    Public Property rootSvnProjectPath As String

    Public Function getSVNCurrentRevision() As Integer

        Const lastChangedRev As String = "Revision: "
        Me.executeSVNCommand("update")
        Dim result As String = Me.executeSVNCommand("info")

        Dim idx1 As Integer = result.IndexOf(lastChangedRev) + lastChangedRev.Length
        Dim idx2 As Integer = result.IndexOf(vbCrLf, idx1)
        Dim rev As String = result.Substring(idx1, idx2 - idx1)

        Return CInt(rev)

    End Function

    Public Function getSVNModifiedFileList(ByVal revisionFrom As Integer, _
                                           Optional ByVal revisionTo As Integer = 0) As List(Of String)

        'diff -r 305:HEAD --summarize
        Dim srevisionTo As String = CStr(revisionTo)
        If revisionTo = 0 Then
            srevisionTo = "HEAD"
        End If
        Dim command As String = String.Format("diff -r {0}:{1} --summarize", revisionFrom, srevisionTo)
        Dim result As String = Me.executeSVNCommand(command)

        Dim ret As New List(Of String)

        Return ret

    End Function

    Public Function SvnUpdateAndGetImportedFileList() As List(Of IExportedAccessObject)

        'called from the SVN menues
        'Does an svn update and loads modified files.  After that, it sets the current version in the database properties
        'Example commands executed:
        'svn update
        'svn diff -r 326 --summarize http://supernova-consulting.unfuddle.com/svn/supernova-consulting_snv/Payroll-SQL/trunk > svndiff.txt
        '
        Dim objectList As New List(Of IExportedAccessObject)
        Dim tmpfile As String

        Dim ln As String
        Dim diffCommand As String
        Dim svnRepository As String
        Dim updFile As String

        Dim svnOperation As String
        Dim svnRevision As String

        Dim app As Access.Application = AppContext.getRunningAccessComReference

        svnRevision = AppContext.current.getAccessProperty(app, "svnRevision")
        svnRepository = AppContext.current.getAccessProperty(app, "svnRepository")

        If (svnRepository = "") Then
            Throw New ApplicationException("svnRepository database property not set")
        End If
        If (svnRevision = "") Then
            Throw New ApplicationException("svnRevision database property not set")
        End If

        diffCommand = " diff -r " & svnRevision & " --summarize " & svnRepository

        tmpfile = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) & "\svndiff.txt"
        If File.Exists(tmpfile) Then
            File.Delete(tmpfile)
        End If

        Call executeSVNCommand(" update")
        Using txtStream As New StringReader(executeSVNCommand(diffCommand))

            Do While True

                ln = txtStream.ReadLine
                If ln Is Nothing Then
                    Exit Do
                End If

                updFile = Replace(Mid(ln, 9), svnRepository, "")
                If updFile.StartsWith("/") OrElse updFile.StartsWith("\") Then
                    updFile = Mid(updFile, 2)
                End If
                If updFile.ToLower.StartsWith("modules") OrElse updFile.ToLower.StartsWith("forms") _
                     OrElse updFile.ToLower.StartsWith("reports") Then

                    updFile = Replace(updFile, "/", "\")'remove leading "/" and convert all \ to /
                    svnOperation = Left(ln, 1)

                    Dim lNewExportedAccessObject As ExportedAccessObject = New ExportedAccessObject( _
                                                       updFile, _
                                                        svnOperation)

                    objectList.Add(lNewExportedAccessObject)
                    Console.WriteLine(updFile)
                End If

            Loop
        End Using

        Return objectList

    End Function

    Public Sub Update()

        Me.executeSVNCommand("update")

    End Sub
    Private Function executeSVNCommand(ByVal args As String) As String

        Dim oProcess As New Process()
        Dim oStartInfo As New ProcessStartInfo(Me.svnExecutablePath, args)
        Console.WriteLine("Executing SVN Command:" & Me.svnExecutablePath & " " & args)

        oStartInfo.UseShellExecute = False
        oStartInfo.WorkingDirectory = Me.rootSvnProjectPath
        oStartInfo.RedirectStandardOutput = True
        oStartInfo.CreateNoWindow = True

        oProcess.StartInfo = oStartInfo
        oProcess.Start()

        Dim sOutput As String

        Using oStreamReader As System.IO.StreamReader = oProcess.StandardOutput
            sOutput = oStreamReader.ReadToEnd()
        End Using
        Console.WriteLine("Executed SVN Command output:" & sOutput)
        Console.WriteLine("-----------------------")
        Return sOutput

    End Function

    Function getSVNRepository() As String

        Const surl As String = "URL: "

        Dim result As String = Me.executeSVNCommand("info")

        Dim idx1 As Integer = result.IndexOf(surl) + surl.Length
        Dim idx2 As Integer = result.IndexOf(vbCrLf, idx1)
        Dim reposUrl As String = result.Substring(idx1, idx2 - idx1)

        Return reposUrl

    End Function

End Class
